package com.example.yiznspringtestinterface.aop;

import com.alibaba.fastjson.JSON;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * project : my-learn
 * <p> 切面 </p>
 *
 * @author yisl
 * @date 2023-01-05【星期四】
 **/
@Component
@Aspect
public class OperateAspect {
    /**
     * 定义切入点
     * 横切逻辑
     * 植入
     */

    private ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100));

    @Pointcut("@annotation(com.example.yiznspringtestinterface.aop.RecordOperate)")
    public void pointCut(){}

    @Around("pointCut()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object result = proceedingJoinPoint.proceed();
        threadPoolExecutor.execute(() -> {
            try {
                MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
                RecordOperate annotation = signature.getMethod().getAnnotation(RecordOperate.class);

                Class<? extends Convert> convert = annotation.convert();
                Convert convert1 = convert.newInstance();
                OperateLog operateLog1 = convert1.convert(proceedingJoinPoint.getArgs()[0]);


                OperateLog operateLog = new OperateLog();
                operateLog.setDesc(annotation.desc());
                operateLog.setResult(result.toString());
                operateLog.setOrderId(operateLog1.getOrderId());

                System.out.println("insert operateLog" + JSON.toJSONString(operateLog));
            } catch (InstantiationException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        });
        return result;

    }
}
